package school30;

import java.io.InputStream;
import java.util.Vector;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Image;
import school30.ui.Painter;
import school30.ui.State;

public class AppChooser extends School30App {

    public final Object lock = new Object();
    public boolean destroying = false;
    public int icon_size = 60;
    public int app_size = 80;
    protected int scrolling = 0;
    protected int rows_per_screen = 0;
    protected int apps_per_row = 0;
    protected int selectedAppIndex = 0;
    protected Vector icons = new Vector();
    protected Font nameFont = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN,
            Font.SIZE_SMALL);

    public void startApp() {
        Painter p = getPainter();
        app_size = Math.min(getWidth(), getHeight()) / 4;
        icon_size = app_size / 4 * 3;
        rows_per_screen = getHeight() / app_size;
        apps_per_row = getWidth() / app_size;
        loadAppList();

        while (!destroying) {
            synchronized (lock) {
                int sx = app_size / 2;
                int sy = app_size / 2 - scrolling * app_size;
                p.setColor(0x000000);
                p.fillRectangle(0, 0, getWidth(), getHeight());
                p.setFont(nameFont);
                for (int i = 0; i < icons.size(); i++) {
                    if (i == selectedAppIndex) {
                        continue;
                    }
                    AppIcon ai = (AppIcon) icons.elementAt(i);
                    int x = sx + (i % apps_per_row) * app_size;
                    int y = sy + (i / apps_per_row) * app_size;
                    p.drawImage(ai.image, x, y, Painter.HCENTER | Painter.VCENTER);
                    p.setColor(0xffffff);
                    p.drawString(ai.name, x, y + app_size / 2,
                            Painter.HCENTER | Painter.BOTTOM);
                }
                // Draw selected app
                AppIcon ai = (AppIcon) icons.elementAt(selectedAppIndex);
                int x = sx + (selectedAppIndex % apps_per_row) * app_size;
                int y = sy + (selectedAppIndex / apps_per_row) * app_size;
                p.setColor(0x000000);
                p.fillRectangle(x - app_size / 2, y - app_size / 2,
                        app_size, app_size);
                p.drawImage(ai.image, x, y, Painter.HCENTER | Painter.VCENTER);
                p.setColor(0x00ff00);
                p.drawRectangle(x - app_size / 2,
                        y - app_size / 2, app_size, app_size);
                p.setColor(0xffffff);
                p.drawString(ai.name, x, y + app_size / 2,
                        Painter.HCENTER | Painter.BOTTOM);
                try {
                    lock.wait();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    public void loadAppList() {
        try {
            String appList = getResource("/AppList");
            String[] apps = split(appList, '\n');
            for (int i = 0; i < apps.length; i++) {
                if (apps[i].startsWith("#")) {
                    continue;
                }
                String[] item = split(apps[i], ' ');
                AppIcon ai = new AppIcon();
                ai.path = item[0];
                ai.image = resizeImage(Image.createImage(item[1]),
                        icon_size, icon_size);
                ai.name = item[2];
                icons.addElement(ai);
            }
        } catch (Exception ex) {
            System.err.println("Error: couldn't load AppList.");
            ex.printStackTrace();
        }

    }

    public void startChoosedApp() {
        try {
            String path = ((AppIcon) icons.elementAt(selectedAppIndex)).path;
            final School30App app = (School30App) Class.forName(path).newInstance();
            MainMIDlet.mainMIDlet.curApp = app;
            MainMIDlet.mainMIDlet.apps.addElement(app);
            setState(State.BACKGROUND);
            app.setState(State.FOREGROUND);
            Thread appRunnable = new Thread(
                    new Runnable() {
                        public void run() {
                            app.startApp();
                        }
                    });
            appRunnable.start();
        } catch (InstantiationException ex) {
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }

    }

    public void terminateApp() {
        destroying = true;
        synchronized (lock) {
            lock.notifyAll();
        }
    }

    public void keyPressed(int keycode) {
        if (keycode == Canvas.KEY_NUM2) {
            selectedAppIndex -= apps_per_row;
        } else if (keycode == Canvas.KEY_NUM8) {
            selectedAppIndex += apps_per_row;
        } else if (keycode == Canvas.KEY_NUM4) {
            selectedAppIndex -= 1;
        } else if (keycode == Canvas.KEY_NUM6) {
            selectedAppIndex += 1;
        } else if (keycode == Canvas.KEY_NUM5) {
            startChoosedApp();
        }
        if (selectedAppIndex >= icons.size()) {
            selectedAppIndex = icons.size() - 1;
        }
        if (selectedAppIndex < 0) {
            selectedAppIndex = 0;
        }
        int min_row = scrolling + 1;
        int max_row = scrolling + rows_per_screen - 1;
        if (selectedAppIndex / apps_per_row < min_row) {
            scrolling--;
        }
        if (selectedAppIndex / apps_per_row > max_row) {
            scrolling++;
        }

        synchronized (lock) {
            lock.notifyAll();
        }
    }

    public void keyReleased(int keycode) {
    }

    public String getResource(String file) throws Exception {
        InputStream is = getClass().getResourceAsStream(file);
        int len = 0;
        byte[] data = new byte[64];
        StringBuffer sb = new StringBuffer();
        while ((len = is.read(data)) != -1) {
            sb.append(new String(data, 0, len));
        }
        is.close();
        return sb.toString();
    }

    public static Image resizeImage(Image temp, int newX, int newY) {
        int rgb[] = new int[temp.getWidth() * temp.getHeight()];
        temp.getRGB(rgb, 0, temp.getWidth(), 0, 0, temp.getWidth(), temp.getHeight());
        int rgb2[] = reescalaArray(rgb, temp.getWidth(), temp.getHeight(), newX, newY);
        Image temp2 = Image.createRGBImage(rgb2, newX, newY, true);
        return temp2;
    }

    public static String[] split(String s, char del) {
        Vector tokens = new Vector();
        int ld = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == del) {
                if (i != ld) {
                    tokens.addElement(s.substring(ld, i));
                }
                ld = i + 1;
            }
        }
        if (ld != s.length()) {
            tokens.addElement(s.substring(ld, s.length()));
        }
        String[] arr = new String[tokens.size()];
        tokens.copyInto(arr);
        return arr;
    }

    public static int[] reescalaArray(int[] ini, int x, int y, int x2, int y2) {
        int out[] = new int[x2 * y2];
        for (int yy = 0; yy < y2; yy++) {
            int dy = yy * y / y2;
            for (int xx = 0; xx < x2; xx++) {
                int dx = xx * x / x2;
                out[(x2 * yy) + xx] = ini[(x * dy) + dx];
            }
        }
        return out;
    }

    static class AppIcon {

        Image image;
        String name;
        String path;
    }
}
